package com.cdu.service.impl;

import com.cdu.commons.MallConstants;
import com.cdu.commons.ServiceCode;
import com.cdu.commons.ServiceException;
import com.cdu.mapper.ProductMapper;
import com.cdu.pojo.dto.*;
import com.cdu.pojo.entity.Product;
import com.cdu.pojo.entity.ProductCategory;
import com.cdu.pojo.entity.User;
import com.cdu.pojo.vo.CategoryVO;
import com.cdu.pojo.vo.PageVO;
import com.cdu.pojo.vo.ProductVO;
import com.cdu.service.ProductService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ProjectName: cdu-app
 * @Titile: ProductServiceImpl
 * @Author: Administrator
 * @Description: 商品业务实现类
 */
@Service
@Slf4j
public class ProductServiceImpl implements ProductService {
    @Autowired
    private ProductMapper productMapper;

    @Override
    public PageVO<ProductVO> getProductListByPage(ProductQueryDTO productQueryDTO, User user) {
        //判断分类id是否存在
        if (productQueryDTO == null || productQueryDTO.getCategoryId() == null) {
            throw new ServiceException("分类id不能为空", ServiceCode.REQUEST_ERROR);
        }
        //设置分页参数
        PageHelper.startPage(productQueryDTO.getPageNum(), productQueryDTO.getPageSize());
        //判断用户的编号
        Integer userId = user != null ? user.getId() : null;
        Page<ProductVO> list = (Page<ProductVO>) productMapper.getProductListByCategoryId(productQueryDTO.getCategoryId(), userId);
        if (list == null || list.isEmpty()) {
            throw new ServiceException("没有查询到数据", ServiceCode.DATA_NOT_FOUND);
        }
        //重新封装成PageVO
        PageVO<ProductVO> pageVO = new PageVO<>();
        pageVO.setPageNum(list.getPageNum());//页码值
        pageVO.setPageSize(list.getPageSize());//每页数据量
        pageVO.setTotal(list.getTotal());//总数据量
        pageVO.setPages(list.getPages());//总页码
        pageVO.setPageData(list.getResult());//具体数据
        return pageVO;
    }

    @Override
    public void addProduct(ProductAddDTO productAddDTO) {
        // 打印接收到的DTO数据
        log.debug("接收到的商品数据DTO:{}", productAddDTO);

        // 1. 转换DTO为实体
        Product product = new Product();
        BeanUtils.copyProperties(productAddDTO, product);

        // 打印转换后的实体数据
        log.debug("转换后的商品实体:{}", product);

        // 手动设置价格(如果发现BeanUtils没有正确复制)
        if (product.getPrice() == null && productAddDTO.getPrice() != null) {
            product.setPrice(productAddDTO.getPrice());
            log.debug("手动设置价格后的商品实体:{}", product);
        }

        // 2. 设置默认值
        product.setStatus(MallConstants.PRODUCT_STATUS_ON);
        product.setCreatedUser("admin");
        product.setCreatedTime(new Date());
        product.setModifiedUser("admin");
        product.setModifiedTime(new Date());

        // 打印最终要保存的数据
        log.debug("最终保存的商品数据:{}", product);

        // 3. 插入数据库
        int rows = productMapper.insertProduct(product);
        if (rows != 1) {
            throw new ServiceException("添加商品失败", ServiceCode.INSERT_ERROR);
        }
    }

    @Override
    public void updateProductStatus(ProductStatusDTO statusDTO) {
        // 1. 参数校验
        if (statusDTO.getStatus() != MallConstants.PRODUCT_STATUS_ON
                && statusDTO.getStatus() != MallConstants.PRODUCT_STATUS_OFF) {
            throw new ServiceException("商品状态值无效", ServiceCode.UPDATE_ERROR);
        }

        // 2. 更新状态
        int rows = productMapper.updateProductStatus(statusDTO.getId(), statusDTO.getStatus());
        if (rows != 1) {
            throw new ServiceException("更新商品状态失败", ServiceCode.UPDATE_ERROR);
        }
    }

    @Override
    public List<CategoryVO> getCategoryList() {
        // 1. 获取所有分类
        List<ProductCategory> categories = productMapper.selectAllCategories();

        // 2. 转换为树形结构
        List<CategoryVO> result = new ArrayList<>();

        // 2.1 先找出所有一级分类
        List<ProductCategory> parentCategories = categories.stream()
                .filter(c -> c.getParentId() == 0)
                .collect(Collectors.toList());

        // 2.2 递归构建分类树
        for (ProductCategory parent : parentCategories) {
            CategoryVO parentVO = new CategoryVO();
            BeanUtils.copyProperties(parent, parentVO);

            // 递归设置子分类
            setChildren(parentVO, categories);

            result.add(parentVO);
        }

        return result;
    }

    /**
     * 递归设置子分类
     */
    private void setChildren(CategoryVO parent, List<ProductCategory> allCategories) {
        List<CategoryVO> children = new ArrayList<>();

        for (ProductCategory category : allCategories) {
            if (category.getParentId().equals(parent.getId())) {
                CategoryVO child = new CategoryVO();
                BeanUtils.copyProperties(category, child);

                // 递归设置子分类的子分类
                setChildren(child, allCategories);

                children.add(child);
            }
        }

        parent.setChildren(children);
    }

    @Override
    public void updateProduct(ProductUpdateDTO productUpdateDTO) {
        // 1. 检查商品是否存在
        Product existProduct = productMapper.getProductById(productUpdateDTO.getId());
        if (existProduct == null) {
            throw new ServiceException("商品不存在", ServiceCode.DATA_NOT_FOUND);
        }

        // 2. 转换DTO为实体
        Product product = new Product();
        BeanUtils.copyProperties(productUpdateDTO, product);

        // 3. 设置修改人和修改时间
        product.setModifiedUser("admin"); // TODO: 从token中获取
        product.setModifiedTime(new Date());

        // 4. 更新数据库
        int rows = productMapper.updateProduct(product);
        if (rows != 1) {
            throw new ServiceException("更新商品失败", ServiceCode.UPDATE_ERROR);
        }
    }

    @Override
    public Product getProductById(Integer id) {
        Product product = productMapper.getProductById(id);
        if (product == null) {
            throw new ServiceException("商品不存在", ServiceCode.DATA_NOT_FOUND);
        }
        return product;
    }
}